#pragma once

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include "Log.hpp"
#include "Connection.hpp"

using namespace log_ns;

const static int buffersize = 512;

// 不应该让HandlerConnection来处理报文
class HandlerConnection
{
public:
    HandlerConnection(handler_t process) :_process(process)
    {}
    void HandlerRecver(Connection *conn) // conn就是就绪的conn
    {
        // LOG(DEBUG,"client 给我发了消息: %d\n",conn->Sockfd());
        errno = 0;
        // 1.直接读取
        while(true)
        {
            char buffer[buffersize];
            ssize_t n = ::recv(conn->Sockfd(),buffer,sizeof(buffer)-1,0); 
            if(n > 0)
            {
                buffer[n] = 0; // 数据块
                conn->AppendInBuffer(buffer); // 读到的数据块拼接到inbuffer
            }
            // else if(n == 0)
            // {
            //     LOG(INFO,"客户端 [%s:%d]推出了,服务器准备关闭: %d\n",conn->_addr.AddrStr().c_str(),conn->Sockfd());
            //     conn->_handler_excepter(conn); // 统一处理异常
            // }
            else 
            {
                if(errno == EWOULDBLOCK)
                {
                    break;
                }
                else if(errno == EINTR)
                {
                    continue;
                }
                else
                {
                    conn->_handler_excepter(conn); // 统一处理异常
                    return;
                }
            }
        }
        //  2.交给业务处理
        // 一定是读取完毕了，我们应该处理数据了
        std::cout << "Inbuffer 内容: " << conn->Inbuffer() << std::endl;
        _process(conn); // 内容分析
    }
    void HandlerSender(Connection *conn)
    {
        errno = 0;
        // 1.直接写
        while(true)
        {
            ssize_t n = ::send(conn->Sockfd(),conn->OutBuffer().c_str(),conn->OutBuffer().size(),0);
            if(n > 0)
            {
                conn->DiscardOutBuffer(n);
                if(conn->OutBuffer().empty()) break;
            }
            else if(n == 0)
            {
                break;
            }
            else
            {
                // 缓冲区写满，发送条件不满足
                if(errno == EWOULDBLOCK)
                {
                    break;
                }
                else if(errno == EINTR)
                {
                    continue;
                }
                else
                {
                    // 发送失败
                    conn->_handler_excepter(conn);
                    return;
                }
            }
        }
        // 2.只能是发送条件不满足 && 缓冲区还有数据
        if(!conn->OutBuffer().empty())
        {
            // 开启对写事件的关心
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(),true,true); 
            // 发送完了呢？
        }
        else
        {
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(),true,false);
        }
    }
    void HandlerExcepter(Connection *conn)
    {
        // 整个代码的所有逻辑异常处理，全部都在这里
        // 删除链接
        conn->_R->DelConnection(conn->Sockfd());
    }
private:
    handler_t _process;
};